<template>
  <div id="app">
  </div>
</template>

<script>
import * as THREE from 'three';
import {TrackballControls} from "./assets/TrackballControls";
// import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'
// require('three-orthographic-trackball-controls')

// import { GUI } from 'three/examples/jsm/libs/dat.gui.module.js';

// import { TrackballControls } from 'three/examples/jsm/controls/TrackballControls';

// import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js';
// import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js';
import {GLTFLoader} from "three/examples/jsm/loaders/GLTFLoader";

// const cameras = [ 'Orthographic', 'Perspective' ];
// const cameraType = { type: 'Orthographic' };

const perspectiveDistance = 2.5;
const orthographicDistance = 120;
// eslint-disable-next-line no-unused-vars
let camera, controls, scene, renderer, gui, meshGroup;
// let folderOptions, folderAnimations;

let regionPostion = new THREE.Vector3();

const arcballGui = {

  gizmoVisible: true,

  reset: function() {
    let sceneBox = new THREE.Box3();
    sceneBox.setFromObject(scene);
    sceneBox.getCenter(controls.target);
    let vecDiagonal = new THREE.Vector3();
    vecDiagonal.subVectors(sceneBox.max, sceneBox.min);
    let diagonalLength = vecDiagonal.length();
    let tempValue = 1.3 * diagonalLength;
    camera.up.set(0, 0, 1);
    camera.position.copy(controls.target).y -= tempValue;

  },

  panChange: function() {
    // 是旋转，且 control 目标不为 0
    if (controls.target.equals(regionPostion) && !controls.target.equals(new THREE.Vector3())) {
      controls.target = meshGroup.position;
      // controls.reset();
      // camera.lookAt(controls.target)
      // controls.target.set( 0, 0, 0 );
    }
  },

  panStart: function() {
    regionPostion.copy(controls.target)
  },

  // eslint-disable-next-line no-unused-vars
  setArcballControls: function (target) {

    controls = new TrackballControls( camera, renderer.domElement, target );
    console.log('controls is ', controls);

    // import
    controls.enableZoom = true;
    controls.enablePan = true;
    controls.rotateSpeed = 1.2;
    controls.zoomSpeed = 5;
    controls.panSpeed = 200;
    controls.staticMoving = true;
    controls.dynamicDampingFactor = 0.3
    // controls.target = target.position;


    // controls.addEventListener( 'change', render );
    // controls.addEventListener( 'change', this.panChange );
    // controls.addEventListener( 'start', this.panStart );

    this.gizmoVisible = true;

    this.populateGui();

  },

  populateGui: function () {
    //
    // folderOptions.add( controls, 'enabled' ).name( 'Enable controls' );
    // folderOptions.add( controls, 'enableGrid' ).name( 'Enable Grid' );
    // folderOptions.add( controls, 'enableRotate' ).name( 'Enable rotate' );
    // folderOptions.add( controls, 'enablePan' ).name( 'Enable pan' );
    // folderOptions.add( controls, 'enableZoom' ).name( 'Enable zoom' );
    // folderOptions.add( controls, 'cursorZoom' ).name( 'Cursor zoom' );
    // folderOptions.add( controls, 'adjustNearFar' ).name( 'adjust near/far' );
    // folderOptions.add( controls, 'scaleFactor', 1.1, 10, 0.1 ).name( 'Scale factor' );
    // folderOptions.add( controls, 'minDistance', 0, 50, 0.5 ).name( 'Min distance' );
    // folderOptions.add( controls, 'maxDistance', 0, 50, 0.5 ).name( 'Max distance' );
    // folderOptions.add( controls, 'minZoom', 0, 50, 0.5 ).name( 'Min zoom' );
    // folderOptions.add( controls, 'maxZoom', 0, 50, 0.5 ).name( 'Max zoom' );
    // folderOptions.add( arcballGui, 'gizmoVisible' ).name( 'Show gizmos' ).onChange( function () {
    //
    //   controls.setGizmosVisible( arcballGui.gizmoVisible );
    //
    // } );
    // folderOptions.add( controls, 'copyState' ).name( 'Copy state(ctrl+c)' );
    // folderOptions.add( controls, 'pasteState' ).name( 'Paste state(ctrl+v)' );
    // folderOptions.add( controls, 'reset' ).name( 'Reset' );
    // folderAnimations.add( controls, 'enableAnimations' ).name( 'Enable anim.' );
    // folderAnimations.add( controls, 'dampingFactor', 0, 100, 1 ).name( 'Damping' );
    // folderAnimations.add( controls, 'wMax', 0, 100, 1 ).name( 'Angular spd' );

  }

};


function init() {

  const container = document.getElementById('app')
  document.body.appendChild( container );

  renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
  renderer.setPixelRatio( window.devicePixelRatio );
  renderer.setSize( window.innerWidth, window.innerHeight );

  renderer.outputEncoding = THREE.sRGBEncoding;
  renderer.toneMapping = THREE.ReinhardToneMapping;
  renderer.toneMappingExposure = 3;
  renderer.domElement.style.background = 'linear-gradient( 180deg, rgba( 0,0,0,1 ) 0%, rgba( 128,128,255,1 ) 100% )';
  container.appendChild( renderer.domElement );

  //

  scene = new THREE.Scene();
  // scene.add( new THREE.HemisphereLight( 0x443333, 0x222233, 4 ) );
  var AmLight = new THREE.AmbientLight(0x303030);
  AmLight.intensity = 2;
  scene.add(AmLight);
  var pointLight = new THREE.PointLight("#dddddd");
  pointLight.position.set(0, 0, 1000);
  pointLight.intensity = 1;
  pointLight.distance = 5000;
  scene.add(pointLight);

  camera = makeOrthographicCamera();
  camera.position.set( 0, 0, perspectiveDistance );

  // arcballGui.setArcballControls();

  // const material = new THREE.MeshStandardMaterial();

  function animate() {

    requestAnimationFrame( animate );

    controls.update();

    render();

  }

  const group = new THREE.Group();
  scene.add(group);
  arcballGui.setArcballControls(group);
  animate()

  let loadManager = new THREE.LoadingManager();
  const loader = new GLTFLoader(loadManager);
  // const filecolor = '#606060'
  // const opacity = 1;
  loader.load('/models/Duck.glb', function (geometry) {
    // var material = new THREE.MeshLambertMaterial({
    //   // color: geometry.scene.children[0].material.color,
    //   // emissive: geometry.scene.children[0].material.color,
    //   // emissiveMap: geometry.scene.children[0].material.map,
    //   color: filecolor,
    //   opacity : opacity,
    //   transparent:true,
    //   depthWrite: true,
    //   depthTest: true,
    //   // side:THREE.DoubleSide,
    // }); //材质对象Material
    // const mesh = new THREE.Mesh(geometry.scene.children[1].geometry, material);
    // mesh.name = '测试';
    //
    // scene.add(geometry.scene.children[0])
    // const mesh = geometry.scene.children[0];
    // mesh.material.color.set(filecolor);
    // mesh.material.transparent = true;
    // mesh.material.opacity = opacity;
    group.add(geometry.scene);

    // console.log('get mesh', mesh, geometry.scene.children[0]);

  });

  /**
  new OBJLoader()
      .setPath( 'models/obj/cerberus/' )
      .load( 'Cerberus.obj', function ( group ) {

        meshGroup = group;

        const textureLoader = new THREE.TextureLoader().setPath( 'models/obj/cerberus/' );

        material.roughness = 1;
        material.metalness = 1;

        const diffuseMap = textureLoader.load( 'Cerberus_A.jpg', render );
        diffuseMap.encoding = THREE.sRGBEncoding;
        material.map = diffuseMap;

        material.metalnessMap = material.roughnessMap = textureLoader.load( 'Cerberus_RM.jpg', render );
        material.normalMap = textureLoader.load( 'Cerberus_N.jpg', render );

        material.map.wrapS = THREE.RepeatWrapping;
        material.roughnessMap.wrapS = THREE.RepeatWrapping;
        material.metalnessMap.wrapS = THREE.RepeatWrapping;
        material.normalMap.wrapS = THREE.RepeatWrapping;


        group.traverse( function ( child ) {

          if ( child.isMesh ) {

            child.material = material;

          }

        } );

        group.rotation.y = Math.PI / 2;
        group.position.x += 0.25;
        scene.add( group );
        arcballGui.setArcballControls(group);
        animate()
        // render();

        new RGBELoader()
            .setDataType( THREE.UnsignedByteType )
            .setPath( 'textures/equirectangular/' )
            .load( 'venice_sunset_1k.hdr', function ( hdrEquirect ) {

              hdrEquirect.mapping = THREE.EquirectangularReflectionMapping;

              scene.environment = hdrEquirect;

              render();

            } );


        window.addEventListener( 'resize', onWindowResize );

        //

        gui = new GUI();
        gui.add( cameraType, 'type', cameras ).name( 'Choose Camera' ).onChange( function () {

          setCamera( cameraType.type );

        } );

        // folderOptions = gui.addFolder( 'Arcball parameters' );
        // folderAnimations = folderOptions.addFolder( 'Animations' );

        // arcballGui.setArcballControls();

        render();

      } );
   **/

}

function makeOrthographicCamera() {

  const halfFovV = THREE.MathUtils.DEG2RAD * 45 * 0.5;
  const halfFovH = Math.atan( ( window.innerWidth / window.innerHeight ) * Math.tan( halfFovV ) );

  const halfW = perspectiveDistance * Math.tan( halfFovH );
  const halfH = perspectiveDistance * Math.tan( halfFovV );
  const near = 0.01;
  const far = 2000;
  const newCamera = new THREE.OrthographicCamera( - halfW, halfW, halfH, - halfH, near, far );
  return newCamera;

}

function makePerspectiveCamera() {

  const fov = 45;
  const aspect = window.innerWidth / window.innerHeight;
  const near = 0.01;
  const far = 2000;
  const newCamera = new THREE.PerspectiveCamera( fov, aspect, near, far );
  return newCamera;

}


// eslint-disable-next-line no-unused-vars
function onWindowResize() {

  if ( camera.type == 'OrthographicCamera' ) {

    const halfFovV = THREE.MathUtils.DEG2RAD * 45 * 0.5;
    const halfFovH = Math.atan( ( window.innerWidth / window.innerHeight ) * Math.tan( halfFovV ) );

    const halfW = perspectiveDistance * Math.tan( halfFovH );
    const halfH = perspectiveDistance * Math.tan( halfFovV );
    camera.left = - halfW;
    camera.right = halfW;
    camera.top = halfH;
    camera.bottom = - halfH;

  } else if ( camera.type == 'PerspectiveCamera' ) {

    camera.aspect = window.innerWidth / window.innerHeight;

  }

  camera.updateProjectionMatrix();

  renderer.setSize( window.innerWidth, window.innerHeight );

  render();

}

function render() {

  renderer.render( scene, camera );

}

// eslint-disable-next-line no-unused-vars
function setCamera( type ) {

  if ( type == 'Orthographic' ) {

    camera = makeOrthographicCamera();
    camera.position.set( 0, 0, orthographicDistance );


  } else if ( type == 'Perspective' ) {

    camera = makePerspectiveCamera();
    camera.position.set( 0, 0, perspectiveDistance );

  }

  controls.setCamera( camera );

  render();

}

export default {
  name: 'App',
  mounted() {
    init();
  }
}
</script>
